<?php
declare(strict_types = 1);

namespace Initiating;

use Swoole\Server;
use Initiating\TransactionResources\TxTransaction;
use Communication\TxDatabase;
use Swoole\Coroutine\Client;
use UntilDistributed\Constant;

/**
 * 测试用【不支持注解】
 * @author mg
 *
 */
class MIddleServer
{
    /**
     *  服务配置
     */
    private $config = [
        'host' => '127.0.0.1',
        'port' =>  9507,
    ];

    /**
     * @var Server
     */
    private static $server;

    private $connectConfig = [
        'work_num' => 4,
        'domain' =>  true,
        'task_worker_num' => 1,

    ];


	
	/**
	 * Pid file
	 *
	 * @var string
	 */
	protected $pidFile = '@runtime/wq.pid';
	
	/**
	 * Script file
	 *
	 * @var string
	 */
	protected $scriptFile = '';
	/**
	 * Record started server PIDs and with current workerId
	 *
	 * @var array
	 */
	private $pidMap = [
			'masterPid'  => 0,
			'managerPid' => 0,
			// if = 0, current is at master/manager process.
			'workerPid'  => 0,
			// if < 0, current is at master/manager process.
			'workerId'   => -1,
	];
	/**
	 * The server unique name
	 *
	 * @var string
	 */
	protected $pidName = 'wq';
	

    public function __construct(array $config)
    {
        $this->config = array_merge($config, $this->config);

    }

    public function start(array $connectConfig = []): void
    {
        static::$server = new Server($this->config['host'], $this->config['port'], SWOOLE_PROCESS, SWOOLE_SOCK_TCP);

        $this->connectConfig = array_merge($connectConfig, $this->connectConfig);

        static::$server->set($this->connectConfig);

        static::$server->on('start', [$this, 'onStart']);

        static::$server->on('receive', [$this,  'OnReceive']);

        static::$server->on('shutdown', [$this, 'onShutdown']);

        static::$server->on('WorkerStart', [$this, 'onWorkerStart']);

        static::$server->on('task', [$this, 'onTask']);
        
        static::$server->start();

    }

    public function onTask(Server $server, int$taskId, int $reactorId, string$data) {

        $i = 0;
var_dump($data);
        // while($i < 60) {
        //     $i++;
        // }

        swoole_timer_clear((int)$data);

    }

	/**
	 * 连接
	 */
	public function onShutdown(Server $server)
	{
	

	}
	
	/**
	 * 启动
	 */
	public function onStart(Server $server)
	{
		// Save PID to property
		$this->setPidMap($server);
		
		$masterPid  = $server->master_pid;
		$managerPid = $server->manager_pid;
		
		$pidStr = sprintf('%s,%s', $masterPid, $managerPid);
		$title  = sprintf('%s master process (%s)', $this->pidName, $this->scriptFile);
		
		// Save PID to file
		// Set process title
		swoole_set_process_name($title);
		
	}
	
	/**
	 * 接收
	 */
	public function onReceive(Server $server, int $fd, int $reactor_id, string $data):void
	{
		
		$db = TxDatabase::getInstance()->getConn();
		
		$txClient = new TxTransaction($db);
		
		$txClient->begin();
		
		$db->query('update `account` set money= money-50', []);
		
		$id= $db->affectedCount();
		
		
        if (!$id) {
            $txClient->rollBack();

            $client = $txClient->getTxClientManage();

//             $timerId = swoole_timer_tick(1000, function()use($client) {
                
//                 $res = $client->recv();

//                var_dump($res);

    
//             } );

//             $server->task($timerId, $server->worker_id);
            $server->send($fd, 'ddd');

            return;
        }
        
		$client = new Client(SWOOLE_TCP);
		
		$client->connect('127.0.0.1', 9508, 3);
		
		$client->send('{"group_id":"'.$txClient->getTransGroup()->groupId.'"}');
		
		$res = unserialize($client->recv(3));
        
dump($res);
		
        if ($res->result === Constant::$tx_complete_fail) {
            $txClient->rollBack();
       
            $txClientManager = $txClient->getTxClientManage();

//             $timerId = swoole_timer_tick(1000, function()use($txClientManager) {

//                 var_dump($txClientManager->recv());

//             } );

//             $server->task(timerId, $server->worker_id);

            $server->send($fd, Constant::$tx_complete_fail.PHP_EOL);

            $client->close();
            return;
        }
        $txClient->commit();

        $client->close();
        
        $server->send($fd, "aaa");
	}
	
	/**
	 * 关闭
	 */
	public function onClose(Server $server)
	{
		
	}
	
	
	/**
	 * Worker start event
	 *
	 * @param CoServer $server
	 * @param int      $workerId
	 *
	 * @throws Throwable
	 */
	public function onWorkerStart(Server $server, int $workerId): void
	{
        global $argv;

        if($workerId >= $server->setting['worker_num']) {
            swoole_set_process_name("php {$argv[0]}: task_worker");
        } else {
            swoole_set_process_name("php {$argv[0]}: worker");
        }
		// Save PID and workerId
		$this->pidMap['workerId']  = $workerId;
		$this->pidMap['workerPid'] = $server->worker_pid;
		
		
		
	}
	
	/**
	 * Manager start event
	 *
	 * @param CoServer $server
	 *
	 * @throws Throwable
	 */
	public function onManagerStart(Server $server): void
	{
		// Server pid map
		$this->setPidMap($server);
		
		// Set process title
		swoole_set_process_name(sprintf('%s manager process', $this->pidName));
	
	}
	
	
	/**
	 * Set pid map
	 *
	 * @param CoServer $server
	 */
	protected function setPidMap(Server $server): void
	{
		if ($server->master_pid > 0) {
			$this->pidMap['masterPid'] = $server->master_pid;
		}
		
		if ($server->manager_pid > 0) {
			$this->pidMap['managerPid'] = $server->manager_pid;
		}
	}
	
	/**
	 * 
	 * @param Server $server
	 */
	public function onManagerStop(Server $server): void
	{
		
	}
}